package de.tum.wi.som.rcpsp.excelImport;

/**
 *
 * @author Max
 */
//Importbefehle zum Dateieneinlesen
import java.awt.Frame;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.jfree.ui.RefineryUtilities;

import de.tum.wi.som.rcpsp.business.PriorizationStrategy;
import de.tum.wi.som.rcpsp.business.impl.SerialGenerationSchemeAlgorithm;
import de.tum.wi.som.rcpsp.entities.Activity;
import de.tum.wi.som.rcpsp.entities.Schedule;
import de.tum.wi.som.rcpsp.entities.WorkContentResource;
import de.tum.wi.som.rcpsp.view.RCPSPBarChart;

//Import Klasse, die jeweils pro Sheet die Daten einliest
//Methodenname gibt die Daten, die eingelesen werden an

public class ImportExcel {

	//private String filename = "D:/Dropbox/OM RCPSP/Testdaten_neu/120/j1201_3.xls"; // variable
																					// für
	// Dateibezeichnung
	private Map<String, Activity> activityMap = new HashMap<String, Activity>();
	private File file;
	private PriorizationStrategy priorizationStrategy;
	private static final int START_COLUMN = 1;

	public ImportExcel(File file, PriorizationStrategy priorizationStrategy) {
		this.file=file;
		this.priorizationStrategy= priorizationStrategy;
	}


	public void import_graphs(String sheetname, int resourceColumn) {
		try {
			FileInputStream fileIn = new FileInputStream(file); // Angabe
																	// des
																	// Dateinamens
			HSSFWorkbook workbook = new HSSFWorkbook(fileIn); // Anlegen der
																// Dateistruktur
																// für .xls
																// Dateien
			HSSFSheet worksheet = workbook.getSheet(sheetname); // Anlegen der
																// Datenstruktur
																// für
																// worksheets
			HSSFRow row; // Zeile

			int v = worksheet.getLastRowNum(); // Befehl gibt die Anzahl an
												// Zeilen im Sheet zurueck, die
												// mit Daten gefaellt sind
			int rowNumber = 1;
			int step = 1;
			while (rowNumber <= v) {
				row = worksheet.getRow(rowNumber++);
				if (row.getCell(0) != null
						&& row.getCell(0).getStringCellValue().contains("***")) {
					step++;
					if (step == 2) {
						rowNumber += 3;
					}
					if (step == 3) {
						rowNumber += 2;
						break;
					}
					continue;
				} else if (step == 1) {
					// read Activities and successors
					readCellForNameAndSuccessors(row);
				} else if (step == 2) {
					// read duration and resource usage per time
					readDuration(row, resourceColumn);
				}

			}
			row = worksheet.getRow(rowNumber);
			// minBlockLength, random between 2 and 4.
			WorkContentResource wcr = new WorkContentResource(
					(int) (Math.random() * 3) + 2, new Double(row.getCell(
							START_COLUMN + resourceColumn)
							.getNumericCellValue()).intValue());

			ArrayList<Activity> activities = new ArrayList<Activity>(activityMap.values());
			SerialGenerationSchemeAlgorithm serialGenerationSchemeAlgorithm = new SerialGenerationSchemeAlgorithm();
			serialGenerationSchemeAlgorithm.setPriorizationStrategy(priorizationStrategy);
			Schedule schedule = serialGenerationSchemeAlgorithm
					.createSchedule(
							activities,
							wcr);

			System.out.println(schedule);
			/*final RCPSPChart demo = new RCPSPChart(schedule);
			demo.pack();
			RefineryUtilities.centerFrameOnScreen(demo);
			demo.setVisible(true);*/
			RCPSPBarChart stackedbarchartdemo7 = new RCPSPBarChart("RCPSP", schedule, activities);
			stackedbarchartdemo7.pack();
			RefineryUtilities.centerFrameOnScreen(stackedbarchartdemo7);
			stackedbarchartdemo7.setExtendedState(Frame.MAXIMIZED_BOTH);
			stackedbarchartdemo7.setVisible(true);

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private void readDuration(HSSFRow row, int resourceColumn) {
		Activity activity = findActivity(new Integer(new Double(row.getCell(
				START_COLUMN).getNumericCellValue()).intValue()).toString());
		int duration = new Double(row.getCell(START_COLUMN + 2)
				.getNumericCellValue()).intValue();
		int resourceUsage = new Double(row.getCell(
				START_COLUMN + 2 + resourceColumn).getNumericCellValue())
				.intValue();
		activity.setNeededResources(duration * resourceUsage);
		int lowerBound = Math.max(1, (int) (resourceUsage - Math.random() * 4));
		int upperBound = (int) (resourceUsage + Math.random() * 4);
		activity.setLowerBound(lowerBound);
		activity.setUpperBound(upperBound);
		if(resourceUsage==0){
			deleteActivity(activity);
		}
	}

	private void deleteActivity(Activity activity) {
		Collection<Activity> values = activityMap.values();
		for (Activity activity2 : values) {
			deleteFromPriorActivities(activity2, activity);
			deleteFromFollowerActivities(activity2, activity);
		}
		activityMap.remove(activity.getName());
	}

	private void deleteFromPriorActivities(Activity activity, Activity activityToDelete) {
		Set<Activity> priorActivities = activity.getPriorActivities();
		priorActivities.remove(activityToDelete);
	}
	
	private void deleteFromFollowerActivities(Activity activity, Activity activityToDelete) {
		Set<Activity> followerActivities = activity.getFollowerActivities();
		followerActivities.remove(activityToDelete);
	}

	private void readCellForNameAndSuccessors(HSSFRow row) {
		Activity a = findOrCreateActivity(new Integer(new Double(row.getCell(
				START_COLUMN).getNumericCellValue()).intValue()).toString());
		readSuccessors(a, row, new Double(row.getCell(START_COLUMN + 2)
				.getNumericCellValue()).intValue());
	}

	private void readSuccessors(Activity a, HSSFRow row, int numberOfSuccessors) {
		for (int i = 0; i < numberOfSuccessors; i++) {
			Activity followerActivity = findOrCreateActivity(new Integer(
					new Double(row.getCell(START_COLUMN + 3 + i)
							.getNumericCellValue()).intValue()).toString());
			a.addFollowerActivity(followerActivity);
			followerActivity.addPriorActivity(a);
		}

	}

	private Activity findOrCreateActivity(String nextToken) {
		Activity result = activityMap.get(nextToken);
		if (result == null) {
			result = new Activity();
			result.setName(nextToken);
			activityMap.put(nextToken, result);
		}
		return result;
	}

	private Activity findActivity(String name) {
		Activity activity = activityMap.get(name);
		if (activity == null) {
			throw new IllegalStateException("Cannot find activity " + name);
		}
		return activity;
	}

	public static void main(String[] args) {
		
	}

}
